import { ForbiddenException, HttpException, HttpStatus, Injectable, NotAcceptableException } from '@nestjs/common';
import { InjectRepository, InjectDataSource, InjectEntityManager } from '@nestjs/typeorm';
import { Bk_Product } from 'src/product/bk_product.entity';
import { ProductService } from 'src/product/product.service';
import { Request } from 'express';
import { DeleteResult, Repository, UpdateResult } from 'typeorm';
import { Bk_Order } from './bk_order.entity';

@Injectable()
export class OrderService {
    constructor(
        @InjectRepository(Bk_Order)
        private readonly orderRepository: Repository<Bk_Order>,
        @InjectRepository(Bk_Product)
        private readonly productRepository: Repository<Bk_Product>,
    ) { }
    // 添加订单
    async add(order: any): Promise<Bk_Order> {
        return await this.orderRepository.save(order);
    }
    // 删除订单
    async delete(id: number): Promise<DeleteResult> {
        return await this.orderRepository.delete({ id });
        // 软删除
        // return await this.orderRepository.softDelete({ id });
    }
    // 更新订单
    async update(id: number, order: any): Promise<UpdateResult> {
        return await this.orderRepository.update(id, order);
    }
    // 获取所有订单
    async findAll(query: any): Promise<[Bk_Order[], number]> {
        return await this.orderRepository.findAndCount({ relations: ["product", 'buyer_id', 'product.product_info', 'product.product_info.video'], order: { id: "ASC" }, skip: query.skip, take: query.take });
    }

    // 通过用户id获取订单
    async getOrdersByUserId(query: { userId: number, skip?: number, take?: number }): Promise<[Bk_Order[], number]> {
        return await this.orderRepository.findAndCount({ relations: ["product", 'buyer_id', 'product.product_info', 'product.product_info.video'], order: { id: "DESC" }, where: { buyer_id: { id: query.userId } }, skip: query.skip, take: query.take });
    }
    // 通过商品id获取订单
    async getOrderByProduct(product: { id: number }, buyer_id?: { id: number }): Promise<Bk_Order[]> {
        return await this.orderRepository.find({ relations: ["product", 'buyer_id', 'product.product_info', 'product.product_info.video'], order: { id: "DESC" }, where: { product, buyer_id } });
    }
    // 通过订单编号获取订单
    async getOrderByNumber(orderNumber: string): Promise<Bk_Order> {
        return await this.orderRepository.createQueryBuilder('order')
            .leftJoinAndSelect('order.product', 'product')
            .leftJoinAndSelect('order.buyer_id', 'buyer_id')
            .leftJoinAndSelect('product.product_info', 'product_info')
            .leftJoinAndSelect('product_info.video', 'video')
            .where('order.order_number = :orderNumber', { orderNumber })
            .addSelect('video.file_path').addSelect('product_info.product_url')
            .getOne();
    }
    // 通过id获取订单
    async getOrderById(id: number): Promise<Bk_Order> {
        return await this.orderRepository.findOne({ relations: ["product", 'buyer_id', 'product.product_info', 'product.product_info.video'], where: { id } });
    }

    async verifyOrCreateOrder(option: { order_number?: string, product?: number, user_id: number }): Promise<Bk_Order> {
        if (option.order_number) {
            const order = await this.getOrderByNumber(option.order_number);
            if (!order) {
                throw new NotAcceptableException('支付的订单已被删除');
            }
            if (order.buyer_id.id !== option.user_id) {
                throw new ForbiddenException('没有权限访问此订单')
            }
            return order;
        }
        // 按商品id支付
        if (!option.product) {
            throw new HttpException({
                status: HttpStatus.FORBIDDEN,
                error: '缺少参数：product 或 order_number，这两个参数必须有且只有一个',
            }, HttpStatus.FORBIDDEN)
        }
        if (option.product) {
            const product = await this.productRepository.findOne({ where: { id: option.product } });
            if (product) {
                const userOrders = await this.getOrdersByUserId({ userId: option.user_id });
                // 查找用户是否有当前商品的订单
                const findUserOrders = userOrders[0].filter((order) => {
                    let product;
                    if (Array.isArray(order.product)) {
                        product = order.product[0];
                    } else {
                        product = order.product;
                    }
                    if (product.id == option.product) {
                        return order;
                    }
                });
                if (findUserOrders.length > 0) {
                    // 查看当前用户相关订单是否有已支付状态；
                    const successOrder = findUserOrders.find((order) => {
                        if (order.pay_state === 'SUCCESS') {
                            return order;
                        }
                    });
                    if (successOrder) {
                        return successOrder;
                    }
                    return findUserOrders[0];
                } else {
                    const orderNumber = this.getOrderNumber();
                    const orderOption = {
                        order_number: orderNumber,
                        buyer_id: { id: option.user_id },
                        buy_price: product.product_price,
                        product_name: product.product_name,
                        product: { id: product.id }
                    }
                    return await this.add(orderOption);
                }
            } else {
                throw new NotAcceptableException('要购买的商品不存在');
            }

        }

    }

    //通过订单状态获取订单
    async getOrdersByState(query: any, id: number, request: Request): Promise<Bk_Order[]> {
        const orderState = query.state == 0 ? 'NOTPAY' : 'SUCCESS'
        let orderQueryBuilder = this.orderRepository.createQueryBuilder('order')
            .leftJoinAndSelect('order.product', 'product')
            .leftJoinAndSelect('order.buyer_id', 'buyer_id')
            .leftJoinAndSelect('product.product_info', 'product_info')
            .leftJoinAndSelect('product_info.video', 'video')
            .where('order.buyer_id = :buyer_id', { buyer_id: id })
            .andWhere('order.pay_state = :pay_state', { pay_state: orderState })

        if (orderState == 'SUCCESS'&& request.headers['user-agent'].includes('MicroMessenger')) {
            orderQueryBuilder = orderQueryBuilder.addSelect('video.file_path').addSelect('product_info.product_url')
        }
        return await orderQueryBuilder.getMany();
    }

    //通过订单状态获取订单 分页
    async getOrdersByStateSkip(query: any, id: number, request: Request): Promise<[Bk_Order[], number]> {
        const orderState = query.state == 0 ? 'NOTPAY' : 'SUCCESS'
        let orderQueryBuilder = this.orderRepository.createQueryBuilder('order')
            .leftJoinAndSelect('order.product', 'product')
            .leftJoinAndSelect('order.buyer_id', 'buyer_id')
            .leftJoinAndSelect('product.product_info', 'product_info')
            .leftJoinAndSelect('product_info.video', 'video')
            .where('order.buyer_id = :buyer_id', { buyer_id: id })
            .andWhere('order.pay_state = :pay_state', { pay_state: orderState })
            .take(query.take).skip(query.skip)
        if (orderState == 'SUCCESS'&& request.headers['user-agent'].includes('MicroMessenger')) {
            orderQueryBuilder = orderQueryBuilder.addSelect('video.file_path').addSelect('product_info.product_url')
        }
        return await orderQueryBuilder.getManyAndCount();
    }

    //通过用户id获取订单并且已完成支付
    // async getOrdersByUserId(query: { userId: number, skip?: number, take?: number }): Promise<Bk_Order[]> {
    //     return await this.orderRepository.find({ relations: ["product", 'buyer_id'], order: { id: "DESC" }, where: { buyer_id: { id: query.userId } }, skip: query.skip, take: query.take });
    // }

    getOrderNumber() {
        const now = new Date()
        let month: any = now.getMonth() + 1
        let day: any = now.getDate()
        let hour: any = now.getHours()
        let minutes: any = now.getMinutes()
        let seconds: any = now.getSeconds()
        month = month < 10 ? "0" + month : month;
        day = day < 10 ? "0" + day : day;
        hour = hour < 10 ? "0" + hour : hour;
        minutes = minutes < 10 ? "0" + minutes : minutes;
        seconds = seconds < 10 ? "0" + seconds : seconds;
        let orderCode = now.getFullYear().toString() + month.toString() + day + hour + minutes + seconds + (Math.round(Math.random() * 1000000)).toString();
        return orderCode;
    }
}
